package main

import (
	"context"
	"fmt"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"

	"golang.org/x/time/rate"
)

var (
	route *gin.Engine
)

func init() {
	//gin.DefaultWriter = ioutil.Discard
	//gin.DefaultErrorWriter = ioutil.Discard
	//gin.SetMode(gin.ReleaseMode)
	gin.DisableBindValidation()
}

func Termination(text string) gin.HandlerFunc {
	return func(c *gin.Context) {
		rPath := c.Request.URL.Path
		if rPath == "/getuser" {
			c.Abort()
			c.String(http.StatusUnavailableForLegalReasons, text)
		}
	}
}

func NotFound(text string) gin.HandlerFunc {
	return func(c *gin.Context) {
		if c.Writer.Status() == http.StatusNotFound {
			c.Abort()
			c.String(http.StatusNotFound, text)
		}
	}
}

func RateLimit(text string, rates float64, brust int) gin.HandlerFunc {
	limit := rate.NewLimiter(rate.Limit(rates), brust)
	return func(c *gin.Context) {
		t := time.Now()
		err := limit.Wait(context.TODO())
		if err != nil {
			c.Abort()
			c.String(http.StatusTooManyRequests, text)
		}

		fmt.Println("Wait Cost:", time.Now().Sub(t))
	}
}

func main() {
	route = gin.New()
	route.Use(NotFound("404 page not found"))
	route.Use(Termination("terminated url"))
	route.Use(RateLimit("rate limited", 1, 1))
	route.Use(gin.Logger(), gin.Recovery())

	RegisterHandle("/user", &IndexControl{})
	RegisterHandle("/getuser", &GetUserControl{})

	srv := &http.Server{
		Addr:         ":19911",
		Handler:      http.TimeoutHandler(route, 3*time.Second, ""),
		ReadTimeout:  15 * time.Second,
		WriteTimeout: 10 * time.Second,
	}

	fmt.Println(srv.ListenAndServe())
}
